"""工作空间管理器"""

import uuid
from typing import List, Optional, Dict, Any
from pathlib import Path
from datetime import datetime

from ..models.workspace import Workspace, WorkspaceConfig
from ..utils.database import Database
from ..utils.logger import get_logger


class WorkspaceManager:
    """工作空间管理器"""
    
    def __init__(self, database: Database):
        """初始化工作空间管理器"""
        self.database = database
        self.logger = get_logger()
        self._current_workspace: Optional[Workspace] = None
    
    def create_workspace(self, name: str, root_path: Path) -> Workspace:
        """创建新工作空间"""
        # 验证输入
        if not name or not name.strip():
            raise ValueError("工作空间名称不能为空")
        
        root_path = Path(root_path).resolve()
        
        # 检查路径合法性
        if not self._validate_root_path(root_path):
            raise ValueError(f"无效的根目录路径: {root_path}")
        
        # 检查权限
        if not self._check_permissions(root_path):
            raise PermissionError(f"没有访问路径的权限: {root_path}")
        
        # 检查是否已存在相同路径的工作空间
        existing_workspaces = self.list_workspaces(active_only=False)
        for ws in existing_workspaces:
            if ws.root_path == root_path:
                raise ValueError(f"路径 {root_path} 已被工作空间 '{ws.name}' 使用")
        
        # 创建工作空间
        workspace = Workspace(
            id=str(uuid.uuid4()),
            name=name.strip(),
            root_path=root_path,
            created_at=datetime.now(),
            last_accessed=datetime.now()
        )
        
        try:
            # 保存到数据库
            self.database.save_workspace(workspace)
            
            # 扫描目录结构
            self._scan_directory_structure(workspace)
            
            self.logger.log_workspace_operation(
                workspace_id=workspace.id,
                operation="create",
                result="success",
                workspace_name=workspace.name,
                root_path=str(workspace.root_path)
            )
            
            return workspace
            
        except Exception as e:
            self.logger.log_workspace_operation(
                workspace_id=workspace.id,
                operation="create", 
                result="failed",
                error=str(e)
            )
            raise
    
    def get_workspace(self, workspace_id: str) -> Optional[Workspace]:
        """获取工作空间"""
        try:
            workspace = self.database.get_workspace(workspace_id)
            if workspace and workspace.is_valid_path():
                return workspace
            elif workspace:
                # 路径无效，标记为非活动
                self._deactivate_workspace(workspace_id)
                self.logger.warning(f"工作空间路径无效，已停用", 
                                  workspace_id=workspace_id,
                                  path=str(workspace.root_path))
            return None
            
        except Exception as e:
            self.logger.error(f"获取工作空间失败: {e}", workspace_id=workspace_id)
            return None
    
    def list_workspaces(self, active_only: bool = True) -> List[Workspace]:
        """列出所有工作空间"""
        try:
            workspaces = self.database.list_workspaces(active_only)
            
            # 验证路径有效性
            valid_workspaces = []
            for workspace in workspaces:
                if workspace.is_valid_path():
                    valid_workspaces.append(workspace)
                elif active_only:
                    # 自动停用无效路径的工作空间
                    self._deactivate_workspace(workspace.id)
            
            return valid_workspaces
            
        except Exception as e:
            self.logger.error(f"列出工作空间失败: {e}")
            return []
    
    def switch_workspace(self, workspace_id: str) -> bool:
        """切换当前工作空间"""
        workspace = self.get_workspace(workspace_id)
        if workspace:
            self._current_workspace = workspace
            # 更新最后访问时间
            workspace.last_accessed = datetime.now()
            self.database.save_workspace(workspace)
            
            self.logger.log_workspace_operation(
                workspace_id=workspace_id,
                operation="switch",
                result="success"
            )
            return True
        
        self.logger.log_workspace_operation(
            workspace_id=workspace_id,
            operation="switch",
            result="failed",
            error="workspace not found"
        )
        return False
    
    def get_current_workspace(self) -> Optional[Workspace]:
        """获取当前工作空间"""
        return self._current_workspace
    
    def update_workspace(self, workspace_id: str, **kwargs) -> bool:
        """更新工作空间信息"""
        workspace = self.get_workspace(workspace_id)
        if not workspace:
            return False
        
        try:
            # 更新允许的字段
            allowed_fields = ['name', 'metadata']
            updated = False
            
            for field, value in kwargs.items():
                if field in allowed_fields and hasattr(workspace, field):
                    setattr(workspace, field, value)
                    updated = True
            
            if updated:
                self.database.save_workspace(workspace)
                self.logger.log_workspace_operation(
                    workspace_id=workspace_id,
                    operation="update",
                    result="success",
                    updated_fields=list(kwargs.keys())
                )
            
            return updated
            
        except Exception as e:
            self.logger.error(f"更新工作空间失败: {e}", workspace_id=workspace_id)
            return False
    
    def delete_workspace(self, workspace_id: str, confirm: bool = False) -> bool:
        """删除工作空间"""
        if not confirm:
            raise ValueError("删除工作空间需要明确确认")
        
        workspace = self.get_workspace(workspace_id)
        if not workspace:
            return False
        
        try:
            # 如果是当前工作空间，清除引用
            if self._current_workspace and self._current_workspace.id == workspace_id:
                self._current_workspace = None
            
            # 从数据库删除
            self.database.delete_workspace(workspace_id)
            
            self.logger.log_workspace_operation(
                workspace_id=workspace_id,
                operation="delete",
                result="success",
                workspace_name=workspace.name
            )
            
            return True
            
        except Exception as e:
            self.logger.error(f"删除工作空间失败: {e}", workspace_id=workspace_id)
            return False
    
    def rescan_workspace(self, workspace_id: str) -> bool:
        """重新扫描工作空间目录结构"""
        workspace = self.get_workspace(workspace_id)
        if not workspace:
            return False
        
        try:
            self._scan_directory_structure(workspace)
            self.logger.log_workspace_operation(
                workspace_id=workspace_id,
                operation="rescan",
                result="success"
            )
            return True
            
        except Exception as e:
            self.logger.error(f"重新扫描失败: {e}", workspace_id=workspace_id)
            return False
    
    def get_directory_structure(self, workspace_id: str) -> List[str]:
        """获取工作空间目录结构"""
        try:
            return self.database.get_directory_structure(workspace_id)
        except Exception as e:
            self.logger.error(f"获取目录结构失败: {e}", workspace_id=workspace_id)
            return []
    
    def _validate_root_path(self, path: Path) -> bool:
        """验证根目录路径"""
        try:
            # 检查路径是否存在
            if not path.exists():
                return False
            
            # 检查是否为目录
            if not path.is_dir():
                return False
            
            # 检查是否为系统重要目录
            forbidden_paths = [
                Path('/'),
                Path('/bin'),
                Path('/usr'),
                Path('/sys'),
                Path('/proc'),
                Path('C:\\'),
                Path('C:\\Windows'),
                Path('C:\\Program Files'),
                Path('C:\\Program Files (x86)'),
            ]
            
            # 解析为绝对路径进行比较
            abs_path = path.resolve()
            
            # 允许临时目录（测试环境）
            if '/tmp/' in str(abs_path) or '/var/tmp/' in str(abs_path):
                return True
            
            for forbidden in forbidden_paths:
                try:
                    forbidden_abs = forbidden.resolve()
                    if abs_path == forbidden_abs or forbidden_abs in abs_path.parents:
                        return False
                except:
                    pass
            
            return True
            
        except Exception:
            return False
    
    def _check_permissions(self, path: Path) -> bool:
        """检查路径权限"""
        try:
            # 检查读权限
            if not path.exists() or not path.is_dir():
                return False
            
            # 尝试读取目录
            list(path.iterdir())
            
            # 检查写权限（尝试创建临时文件）
            test_file = path / f".test_write_{uuid.uuid4().hex[:8]}"
            try:
                test_file.touch()
                test_file.unlink()
                return True
            except:
                return False
                
        except Exception:
            return False
    
    def _scan_directory_structure(self, workspace: Workspace) -> None:
        """扫描目录结构"""
        directories = []
        
        try:
            def scan_recursive(current_path: Path, level: int = 0, max_depth: int = 5):
                if level > max_depth:
                    return
                
                try:
                    for item in current_path.iterdir():
                        if item.is_dir() and not item.name.startswith('.'):
                            relative_path = item.relative_to(workspace.root_path)
                            
                            # 提取可能的关键词
                            keywords = self._extract_directory_keywords(item.name)
                            
                            directories.append({
                                'path': str(relative_path),
                                'parent_path': str(relative_path.parent) if relative_path.parent != Path('.') else None,
                                'level': level,
                                'keywords': keywords
                            })
                            
                            # 递归扫描子目录
                            scan_recursive(item, level + 1, max_depth)
                            
                except PermissionError:
                    # 跳过无权限的目录
                    pass
                except Exception as e:
                    self.logger.warning(f"扫描目录失败: {current_path}, 错误: {e}")
            
            # 开始扫描
            scan_recursive(workspace.root_path)
            
            # 统计信息
            total_dirs = len(directories)
            
            # 统计文件数量（可选，可能比较慢）
            total_files = self._count_files(workspace.root_path)
            
            # 更新工作空间统计
            workspace.update_stats(total_dirs, total_files)
            
            # 保存目录索引
            self.database.save_directory_index(workspace.id, directories)
            self.database.save_workspace(workspace)
            
            self.logger.info(f"目录扫描完成", 
                           workspace_id=workspace.id,
                           directories=total_dirs,
                           files=total_files)
            
        except Exception as e:
            self.logger.error(f"目录扫描失败: {e}", workspace_id=workspace.id)
            raise
    
    def _extract_directory_keywords(self, dir_name: str) -> List[str]:
        """提取目录名关键词"""
        import re
        import jieba
        
        # 清理目录名
        cleaned = re.sub(r'[^\w\s\u4e00-\u9fff]', ' ', dir_name)
        
        # 使用jieba进行中文分词
        words = list(jieba.cut(cleaned))
        
        # 过滤短词和数字，保留有意义的词
        keywords = []
        for word in words:
            word = word.strip()
            if len(word) > 1 and not word.isdigit() and not word.isspace():
                keywords.append(word)
        
        return keywords[:5]  # 最多5个关键词
    
    def _count_files(self, path: Path, max_count: int = 10000) -> int:
        """统计文件数量（限制最大数量避免过慢）"""
        count = 0
        try:
            for item in path.rglob('*'):
                if item.is_file():
                    count += 1
                    if count >= max_count:
                        break
        except Exception:
            pass
        
        return count
    
    def _deactivate_workspace(self, workspace_id: str) -> None:
        """停用工作空间"""
        try:
            workspace = self.database.get_workspace(workspace_id)
            if workspace:
                workspace.is_active = False
                self.database.save_workspace(workspace)
        except Exception as e:
            self.logger.error(f"停用工作空间失败: {e}", workspace_id=workspace_id)